<?php

namespace app\admin\command;

use Carbon\Carbon;
use fast\Random;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Db;
use think\Env;
use think\Exception;
use think\Log;
use app\admin\model\pt\Depart as DepartModel;
use app\admin\model\pt\DutyList as DutyModel;
use app\admin\model\pt\AlarmMonth as AlarmModel;
use app\admin\model\pt\PlanMonth as MonthModel;
use app\admin\model\pt\PlanRange as RangeModel;

class CalFee extends Command
{

    // 在CalPersonSalary后运行
    protected function configure()
    {
        $defaultDateId = date('Ym', strtotime('-1 day'));
        $this->setName('calfee')
            ->addOption('date', 'd', Option::VALUE_OPTIONAL, 'date', $defaultDateId)
            ->setDescription('update depart fee  零点并在结算薪资后运行');
    }
    
    protected function execute(Input $input, Output $output)
    {
        @ini_set("memory_limit",'-1');
        $stime=microtime(true);

        $curMonth = $input->getOption('date');
        $logPre = 'cal depart fee ';
        Log::write($logPre . ': 计算部门费用结束, date =>' . $curMonth);
        $curMonthCarbon = Carbon::parse(date('Y-m-d', strtotime($curMonth . "01")));
        $yearId = date('Y', strtotime($curMonth . "01"));
        $monthId = date('n', strtotime($curMonth . "01"));

        
        $startDay = $curMonthCarbon->firstOfMonth()->toDateString();
        $lastDay = $curMonthCarbon->lastOfMonth()->toDateString();

        $startDateId = date('Ymd', strtotime($startDay));
        $endDateId = date('Ymd', strtotime($lastDay));
        $months = Db::name('pt_plan_month')->where('year_id', $yearId)->where('month_id', $monthId)->select();
        $monthData = [];
        foreach ($months as $m) {
            $tmp = [
                'fee_total' => $m['fee_total'],
                'plan_total' => $m['parttime_total'] + $m['intern_total'],
                'parttime_total' => $m['parttime_total'],
                'intern_total' => $m['intern_total'],
            ]; 
            $monthData[$m['pt_depart_id']] = $tmp;
        }
        // 查询对应月已结算了薪资的
        $allDeparts = DepartModel::where('id', '>', '0')->select();
        foreach ($allDeparts as $depart) {
            Db::startTrans();
            try {
                $consumeTotalFee = Db::name('pt_person_salary')->where('pt_depart_id', $depart->id)
                                                        ->where('salary_total', '>', 0)
                                                        ->where('date_id', '>=', $startDateId)
                                                        ->where('date_id', '<=', $endDateId)
                                                        ->sum('salary_total');
                // 计算已消耗人次
                $consumeTotalPersons = Db::name('pt_duty_list')->where('pt_depart_id', $depart->id)
                                                        ->where('date_id', '>=', $startDateId)
                                                        ->where('date_id', '<=', $endDateId)
                                                        ->count('id');

                $alarmModel = AlarmModel::where('pt_depart_id', $depart->id)->where('month_id', $curMonth)->find();
                $params = [];
                $params['month_fee'] = isset($monthData[$depart->id]) ? $monthData[$depart->id]['fee_total'] : 0;
                $params['plan_total'] = isset($monthData[$depart->id]) ? $monthData[$depart->id]['plan_total'] : 0;
                $params['consume_fee'] = $consumeTotalFee;
                $params['consume_total'] = $consumeTotalPersons;
                if (!$alarmModel) {
                    $alarmModel = new AlarmModel();
                    $params['pt_depart_id'] = $depart->id;
                    $params['month_id'] = $curMonth;
                } else {
                    $params['id'] = $alarmModel->id;
                }
                $alarmModel->save($params);
                Db::commit();
            } catch (Exception $e) {
                Db::rollback();
                print_r($e->getTraceAsString());
                Log::write($logPre . ': 人员信息失败, message:'.$e->getMessage() .', date =>' . $curMonth . ', depart id =>'. $depart->id);
            }
        }

        // 计算部门区间计划 
        $rangeModels = RangeModel::where('start_date_id', '>=', $startDateId)->order('start_date_id', 'asc')->select();
        $rangeData = [];
        foreach ($rangeModels as $r) {
            $departId = $r->pt_depart_id; 
            $rangeStartId = $r->start_date_id;
            $rangeEndId = $r->end_date_id;
            // 查询这个范围的
            $consumeTotalFee = Db::name('pt_person_salary')->where('pt_depart_id', $departId)
                                                    ->where('salary_total', '>', 0)
                                                    ->where('date_id', '>=', $rangeStartId)
                                                    ->where('date_id', '<=', $rangeEndId)
                                                    ->sum('salary_total');
            // 计算已消耗人次
            $consumeTotalPersons = Db::name('pt_duty_list')->where('pt_depart_id', $departId)
                                                    ->where('date_id', '>=', $rangeStartId)
                                                    ->where('date_id', '<=', $rangeEndId)
                                                    ->count('id');
            $r->consume_total = $consumeTotalPersons;
            $r->consume_fee = $consumeTotalFee;
            $r->save();
        }

        foreach ($monthData as $departId => $md) {
            $calFeeTotal = $md['fee_total']; 
            $monthFeeTotal = $md['fee_total'];
            $rangeModels = RangeModel::where('pt_depart_id', $departId)->where('start_date_id', 'like', $curMonth . '%')->order('start_date_id', 'asc')->select();
            foreach ($rangeModels as $r) {
                $calFeeTotal = $calFeeTotal - $r->consume_fee;
                $r->remain_fee = $calFeeTotal; 
                $r->remain_percent = round(($calFeeTotal / $monthFeeTotal * 100), 2);
                $r->save();
            }
        }
        
        Log::write($logPre . ': 计算部门费用结束, date =>' . $curMonth);



        $etime=microtime(true);//获取程序执行结束的时间
        $total=$etime-$stime;   //计算差值
        $output->writeln($total);
        $output->info('update person job success');
    }
    

}
